package com.fallsvc.chatroom.controller;

import com.fallsvc.chatroom.common.Constants;
import com.fallsvc.chatroom.component.OnlineUserManager;
import com.fallsvc.chatroom.mapper.MessageMapper;
import com.fallsvc.chatroom.mapper.MessageSessionMapper;
import com.fallsvc.chatroom.model.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.List;

/**
 * @auther falls_vc
 * description:
 * @date 2025/4/30  21:19
 */
@Slf4j
@Component
public class WebSocketAPI extends TextWebSocketHandler {
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private MessageSessionMapper messageSessionMapper;
    @Autowired
    private MessageMapper messageMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // websocket连接建立后自动调用
        log.info("[websocket]  连接建立成功");
        User user =(User) session.getAttributes().get(Constants.USER);
        if(user==null){
            log.info("[websocket] 用户不存在 没有用户id");
            return;
        }
        log.info("[websocket]  获得用户id:"+user.getUserId());
        // 存当前用户 会话
        onlineUserManager.online(user.getUserId(),session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 收到信息时被自动调用
        log.info("[websocket] 收到信息message:{}",message);
        // 1. 获取当前用户信息，后续进行信息转发
        User user =(User) session.getAttributes().get(Constants.USER);
        if(user==null){
            log.info("[websocket] 用户不存在 没有用户id 无法进行信息转发");
            return;
        }
        // 2. 解析信息 json格式的字符串转 Java对象
        MessageRequest request=objectMapper.readValue(message.getPayload(),MessageRequest.class);
        if(request.getType().equals("message")){
            // 进行消息转发
            transferMessage(user,request);
        }else{
            log.info("[websocket] 收到信息格式有误message:{}",request);
        }

    }

    /**
     * 实现信息的转发
     * @param fromUser 发信息用户
     * @param request
     */

    private void transferMessage(User fromUser, MessageRequest request) throws IOException {
        // 1. 创建响应返回对象
        MessageResponse messageResponse=new MessageResponse();
        messageResponse.setFromId(fromUser.getUserId());
        messageResponse.setFromName(fromUser.getUsername());
        messageResponse.setSessionId(request.getSessionId());
        messageResponse.setContent(request.getContent());
        // 转为json字符串转发
        String responseJson=objectMapper.writeValueAsString(messageResponse);
        log.info("[transferMessage] 响应字符串为 "+responseJson);
        // 2. 查询所有需要发送响应对象(包括自己)
        List<Friend> friends= messageSessionMapper.getFriendsBySessionId(request.getSessionId(), fromUser.getUserId());
        // 添加自己
        Friend friend=new Friend();
        friend.setFriendId(fromUser.getUserId());
        friend.setFriendName(fromUser.getUsername());
        friends.add(friend);
        // 3. 发送信息
        for(Friend friend1:friends){
            WebSocketSession webSocketSession=onlineUserManager.getWebSocketSession(friend1.getFriendId());
            if(webSocketSession==null){
                // 用户未在线
                continue;
            }
            webSocketSession.sendMessage(new TextMessage(responseJson));
        }

        // 4. 把信息记录到数据库
        Message message=new Message();
        message.setFromId(fromUser.getUserId());
        message.setFromName(fromUser.getUsername());
        message.setSessionId(request.getSessionId());
        message.setContent(request.getContent());
        messageMapper.add(message);
        log.info("[transferMessage] 信息添加在数据库成功message:{}",message);
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.info("[websocket] 发生异常 e:{}",exception);
        //  发生异常时被自动调用
        User user =(User) session.getAttributes().get(Constants.USER);
        if(user==null){
            log.info("[websocket] 用户不存在 没有用户id");
            return;
        }
        // 用户下线
        onlineUserManager.offline(user.getUserId(),session);
        log.info("[websocket] 用户 ["+user.getUserId()+"] 异常 线下！");
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 正常关闭后调用
        log.info("[websocket] websocket连接关闭");

        User user =(User) session.getAttributes().get(Constants.USER);
        if(user==null){
            log.info("[websocket] 用户不存在 没有用户id");
            return;
        }
        // 用户下线
        onlineUserManager.offline(user.getUserId(),session);
        log.info("[websocket] 用户 ["+user.getUserId()+"] 正常 线下！");

    }
}
